package com.qf.fmall2202.user.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.fmall2202.exception.QFException;
import com.qf.fmall2202.user.entity.User;
import com.qf.fmall2202.user.service.IUsersService;
import com.qf.fmall2202.utils.CommonContants;
import com.qf.fmall2202.utils.R;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

/**
 * <p>
 * 用户  前端控制器
 * </p>
 *
 * @author dong_
 * @since 2022-11-03
 */
@CrossOrigin
@RestController
@RequestMapping("/user")
public class UsersController {

    @Autowired
    IUsersService usersService;

    @GetMapping("/login")
    public R login(String username,String password) throws JsonProcessingException {

        //获取Shiro的subject对象
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(new UsernamePasswordToken(username,password));
        } catch (AuthenticationException e) {
            throw new QFException("用户名或密码错误");
        }
        User user = (User) subject.getPrincipal();

        //生成token ，用于后续的请求验证用户的身份
        String token = creatToken(user);
        //返回json对象
        return R.ok(token).put("data",user);


    }

    /**
     * 创建token字符串
     * 对于token的需求
     * 1.要让服务器端校验token是否合法（是不是服务器端办法的token）
     * 2.token有一个有效期（过期时间）
     * 3.扩展性：我相反给到信息可以自定义存放到token中
     * @param user
     * @return
     */
    private String creatToken(User user) throws JsonProcessingException {
        HashMap<String, Object> map = new HashMap<>();

        //User---->Json
        ObjectMapper objectMapper = new ObjectMapper();
        String userJson = objectMapper.writeValueAsString(user);

        map.put(CommonContants.JWT_CLAIMS_KEY,userJson);
        JwtBuilder builder = Jwts.builder();
        String compact = builder.setClaims(map)
                .setSubject(user.getUsername())
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date())
                .setIssuer(CommonContants.JWT_AUTHOR)
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
                .signWith(SignatureAlgorithm.HS256, CommonContants.JWT_SECRET_KEY)
                .compact();

        return compact;
    }

    @PostMapping("/regist")
    public R regist(@RequestBody User user){

        User u = usersService.regist(user);
        return R.ok().put("data",u);

    }

}
